home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Tools 4
/
Amiga Tools 4.iso
/
tools
/
system-tools
/
dircomp
/
src
/
dircmp2.c
Wrap
C/C++ Source or Header
|
1996-02-26
|
6KB
|
286 lines
/*
dircmp2 command
alpha version 7 & beta version 1, derived from alpha version 6
revision: 4.11.1995
(C) 1995 Thomas Radtke
E-Mail: Thomas.Radtke@rz.uni-osnabrueck.de
covered by the GPL, see COPYING for details
*/
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#define MAXENTRY 1000
#define TABSIZE 2
int tab,rec,inv,cmp,dirs,fls,pathpart,help;
int tabulator=0;
int main(int argc, char **argv)
{
int cnt;
void dircmp2();
rec=0;
inv=0;
cmp=0;
dirs=0;
fls=0;
pathpart=0;
help=0;
tab=0;
cnt=0;
if (argc>1)
{
while (argv[++cnt][0]=='-' && cnt<argc)
{
switch(argv[cnt][1])
{
case 't':
tab=1;
break;
case 'h':
help=1;
break;
case 'p':
pathpart=1;
break;
case 'f':
fls=1;
dirs=0;
break;
case 'i':
inv=1;
break;
case 'd':
dirs=1;
fls=0;
break;
case 'c':
cmp=1;
break;
case 'r':
rec=1;
break;
default:
fprintf(stderr,"%s: unknown option -%c\n",argv[0],argv[cnt][1]);
exit(20);
break;
}
}
argc-=(cnt-1);
}
if (argc<2 || help)
{
fprintf(stderr,"usage: %s [-{cdfhiprt}] directory1 [directory2]\n",*argv);
if (help)
{
fprintf(stderr,"\nThe %s command lists all files and directories of directory1, that\n",*argv);
fprintf(stderr,"cannot be found in directory2. If directory2 is omitted, '.' is used\n\nFlags:\n\n");
fprintf(stderr,"-c compare files\n");
fprintf(stderr,"-d show only directorys\n");
fprintf(stderr,"-f show only files\n");
fprintf(stderr,"-h this page\n");
fprintf(stderr,"-i inverse comparison\n");
fprintf(stderr,"-p show full pathnames\n");
fprintf(stderr,"-r subdir scan\n");
fprintf(stderr,"-t indent subdir results\n");
exit(0);
}
else {
fprintf(stderr,"use option -h to show the help page\n");
exit(20);
}
}
if (argc==3)
dircmp2(*argv,argv[cnt],argv[cnt+1]);
else
dircmp2(*argv,argv[cnt],(char *)".");
exit(0);
}
void dircmp2(char *argv, char *argv1, char *argv2)
{
DIR *dir1,*dir2;
struct dirent *entry;
int d1,d2,s1,s2,equal,ind1,ind2,i,j,k;
struct stat fileinfo,fileinfo2;
char *buf,*buf2,*buffer1,*buffer2;
int fh;
char **dir_name_list_1,**dir_name_list_2;
void tabul();
if (!(dir_name_list_1=(char **)malloc(MAXENTRY*sizeof(char *))))
{
printf("%s: memory exhausted\n",argv);
exit(20);
}
if (!(dir_name_list_2=(char **)malloc(MAXENTRY*sizeof(char *))))
{
printf("%s: memory exhausted\n",argv);
exit(20);
}
if (!(dir1=(DIR *)opendir((char *)argv1)))
{
fprintf(stderr,"%s: nonexistant directory %s\n",argv,argv1);
exit(20);
}
if (!(dir2=(DIR *)opendir((char *)argv2)))
{
fprintf(stderr,"%s: nonexistant directory %s\n",argv,argv2);
closedir(dir1);
exit(20);
}
ind1=0;
ind2=0;
while ((entry=(struct dirent *)readdir(dir1)))
{
if (!strcmp(".",entry->d_name) || !strcmp("..",entry->d_name)) continue;
if (!(dir_name_list_1[ind1]=(char *)malloc(entry->d_namlen+1))) {
printf("%s: memory exhausted\n",argv);
closedir(dir1);
closedir(dir2);
exit(20);
}
strcpy(dir_name_list_1[ind1],entry->d_name);
if (ind1++==MAXENTRY)
{
printf("%s: too much entries\n",argv);
closedir(dir1);
closedir(dir2);
exit(20);
}
}
while ((entry=(struct dirent *)readdir(dir2)))
{
if (!strcmp(".",entry->d_name) || !strcmp("..",entry->d_name)) continue;
if (!(dir_name_list_2[ind2]=(char *)malloc(entry->d_namlen+1))) {
printf("%s: memory exhausted\n",argv);
closedir(dir1);
closedir(dir2);
exit(20);
}
strcpy(dir_name_list_2[ind2],entry->d_name);
if (ind2++==MAXENTRY)
{
printf("%s: too much entries\n",argv);
closedir(dir1);
closedir(dir2);
exit(20);
}
}
for (i=0; i<ind1; i++) {
equal=0;
for (j=0; j<ind2; j++) {
if (!strcmp(dir_name_list_1[i],dir_name_list_2[j])) {
equal=1;
break;
}
}
if ((inv && equal) || (!inv && !equal) || (!inv && equal && (cmp || rec))) {
if (!(buf=(char *)malloc(strlen(dir_name_list_1[i])+strlen(argv1)+2))) {
printf("%s: memory exhausted\n",argv);
closedir(dir1);
closedir(dir2);
exit(20);
}
*buf=(char)0;
strcpy(buf,argv1);
strcat(buf,"/");
strcat(buf,dir_name_list_1[i]);
stat(buf,&fileinfo);
d1=S_ISDIR(fileinfo.st_mode);
if (equal) {
if (!(buf2=(char *)malloc(strlen(dir_name_list_2[j])+strlen(argv2)+2))) {
printf("%s: memory exhausted\n",argv);
closedir(dir1);
closedir(dir2);
exit(20);
}
*buf2=(char)0;
strcpy(buf2,argv2);
strcat(buf2,"/");
strcat(buf2,dir_name_list_2[j]);
stat(buf2,&fileinfo2);
d2=S_ISDIR(fileinfo2.st_mode);
if (d1!=d2) equal=0;
else if (cmp && fileinfo.st_size!=fileinfo2.st_size) equal=0;
else if (!d1 && cmp) {
buffer1=(char *)malloc(fileinfo.st_size+1);
buffer2=(char *)malloc(fileinfo.st_size+1);
if (!buffer1 || !buffer2) {
fprintf(stderr,"%s: warning: memory exhausted\n",argv);
fprintf(stderr,"the files %s and %s are considered to be different\n",buf,buf2);
if (buffer1) free(buffer1);
if (buffer2) free(buffer2);
equal=0;
}
else {
fh=open(buf,O_RDONLY,0);
s1=read(fh,buffer1,fileinfo.st_size);
close(fh);
fh=open(buf2,O_RDONLY,0);
s2=read(fh,buffer2,fileinfo.st_size);
close(fh);
if (s1!=fileinfo.st_size) {
printf("%s: error reading file %s\n",argv,buf);
closedir(dir1);
closedir(dir2);
exit(20);
}
if (s2!=fileinfo.st_size) {
printf("%s: error reading file %s\n",argv,buf2);
closedir(dir1);
closedir(dir2);
exit(20);
}
for (k=0; k<fileinfo.st_size; k++) {
if (buffer1[k]!=buffer2[k]) break;
}
free(buffer1);
free(buffer2);
if (k!=fileinfo.st_size) equal=0;
}
}
}
if (rec && equal && d1) {
tabulator+=TABSIZE;
dircmp2(argv,buf,buf2);
tabulator-=TABSIZE;
}
else if ((inv && equal) || (!inv && !equal)) {
if ((d1 && dirs) || (!d1 && fls) || (!dirs && !fls)) {
if (!pathpart) {
if (tab) tabul();
printf("%s\n",dir_name_list_1[i]);
}
else {
if (tab) tabul();
printf("%s\n",buf);
}
}
}
}
}
closedir(dir1);
closedir(dir2);
free(dir_name_list_1);
free(dir_name_list_2);
return;
}
void tabul()
{
int i;
for (i=0; i<tabulator; i++) printf(" ");
}